<template>
    <div class="validate-input-container mb-3">
        <label v-if="label" class="form-label">{{ label }}</label>

        <input
            v-if="tag === 'input'"
            type="text"
            v-model="inputValue"
            v-bind="$attrs"
            class="form-control"
            :class="{ 'is-invalid': isError }"
        />

        <textarea
            v-else-if="tag === 'textarea'"
            v-model="inputValue"
            v-bind="$attrs"
            class="form-control"
            :class="{ 'is-invalid': isError }"
        />

        <p v-show="isError" class="invalid-feedback">{{ message }}</p>
    </div>
</template>

<script lang="ts">
import { computed, defineComponent, ref, PropType, watch } from 'vue';

import { mitter } from './ValidateForm.vue';

// 大驼峰命名法
type InputType = 'input' | 'textarea';

// 定义校验格式
type RuleProp = {
    type: 'required' | 'email' | 'mobile' | 'custom';
    message: string;
    validator?: () => boolean;
};

export type RuleProps = RuleProp[];

export default defineComponent({
    inheritAttrs: false,
    props: {
        modelValue: {
            type: String,
            required: true
        },
        tag: {
            type: String as PropType<InputType>,
            required: false,
            default: 'input'
        },
        label: String,
        rules: Array as PropType<RuleProps>
    },
    setup(props, ctx) {
        const inputValue = computed({
            set: val => {
                ctx.emit('update:modelValue', val);
            },
            get: () => props.modelValue || ''
        });
        const isError = ref(false);
        const message = ref('');

        const validateInput = () => {
            // 传入了规则
            if (props.rules) {
                const isAllOk = props.rules.every(item => {
                    let isOk = true;
                    message.value = item.message;
                    switch (item.type) {
                        case 'required':
                            isOk = props.modelValue.trim() !== '';
                            break;
                        case 'email':
                            isOk = /^[\w]+@[\w]+\.com$/.test(props.modelValue);
                            console.log(isOk);
                            break;
                        case 'mobile':
                            isOk = /^1[35789]\d{9}$/.test(props.modelValue);
                            break;
                        case 'custom':
                            if (item.validator) {
                                isOk = item.validator();
                            }
                            break;
                        default:
                            break;
                    }
                    return isOk;
                });
                isError.value = !isAllOk;
                return isAllOk;
            }
            return true;
        };

        // 触发校验
        watch([inputValue], () => {
            validateInput();
        });

        // 触发 form-item-created 函数
        mitter.emit('form-item-created', validateInput);

        return { inputValue, isError, message };
    }
});
</script>
